import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
import type { Recordable } from '@vben/types';

import { h } from 'vue';

// 图标地址： https://icon-sets.iconify.design/
import { IconifyIcon } from '@vben/icons';
import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
import { formatPast2, get, isFunction } from '@vben/utils';

import { objectOmit } from '@vueuse/core';
import {
  ElButton,
  ElDropdown,
  ElDropdownItem,
  ElDropdownMenu,
  ElImage,
  ElSwitch,
  ElTag,
} from 'element-plus';

import { DictTag } from '#/components/dict-tag';
import { $t } from '#/locales';

import { getIcon, getTitle, globalButtonConfig } from './button.config';
import { useVbenForm } from './form';

setupVbenVxeTable({
  configVxeTable: (vxeUI) => {
    vxeUI.setConfig({
      grid: {
        align: 'center',
        border: false,
        columnConfig: {
          resizable: true,
        },
        minHeight: 180,
        formConfig: {
          // 全局禁用vxe-table的表单配置，使用formOptions
          enabled: false,
        },
        formOptions: {
          // 搜索栏展开折叠按钮是折叠 true 折叠 false 收起
          collapsed: true,
        },
        proxyConfig: {
          autoLoad: true,
          response: {
            result: ({ data }) => {
              try {
                // console.log('原始响应数据:', data);

                // 格式1: { data: { total: X, list: [...] } }
                if (data?.data?.list && Array.isArray(data.data.list)) {
                  // console.log('检测到格式1: data.data.list');
                  return data.data.list;
                }

                // 格式2: { data: [...] }
                if (data?.data && Array.isArray(data.data)) {
                  // console.log('检测到格式2: data.data (数组)');
                  return data.data;
                }

                // 格式3: 直接返回 list 字段
                if (data?.list && Array.isArray(data.list)) {
                  // console.log('检测到格式3: data.list');
                  return data.list;
                }

                // 格式4: 数据本身就是数组
                if (Array.isArray(data)) {
                  // console.log('检测到格式4: data (数组)');
                  return data;
                }

                console.warn('未识别的数据格式，返回空数组');
                return [];
              } catch (error) {
                console.error('处理响应数据时出错:', error);
                return [];
              }
            },
            total: ({ data }) => {
              try {
                // 格式1: data.data.total
                if (data?.data?.total !== undefined) {
                  return data.data.total;
                }

                // 格式2: data.total
                if (data?.total !== undefined) {
                  return data.total;
                }

                // 格式3: 数据是数组，返回数组长度
                if (Array.isArray(data?.data)) {
                  return data.data.length;
                }

                if (Array.isArray(data)) {
                  return data.length;
                }

                return 0;
              } catch (error) {
                console.error('处理总数时出错:', error);
                return 0;
              }
            },
            message: ({ data }) => {
              return data?.msg || data?.message || '';
            },
          },
          showActiveMsg: true,
          showResponseMsg: false,
        },
        round: true,
        showOverflow: true,
        size: 'small',
      } as VxeTableGridOptions,
    });

    // 表格配置项可以用 cellRender: { name: 'CellImage' },
    vxeUI.renderer.add('CellImage', {
      renderTableDefault(_renderOpts, params) {
        const { column, row } = params;
        const src = row[column.field];
        return h(ElImage, { src, previewSrcList: [src] });
      },
    });

    // 表格配置项可以用 cellRender: { name: 'CellLink' },
    vxeUI.renderer.add('CellLink', {
      renderTableDefault(renderOpts) {
        const { props } = renderOpts;
        return h(
          ElButton,
          { size: 'small', link: true },
          { default: () => props?.text },
        );
      },
    });
    // 表格配置项可以用 cellRender: { name: 'CellDict', props:{dictType: ''} },
    vxeUI.renderer.add('CellDict', {
      renderTableDefault(renderOpts, params) {
        const { props } = renderOpts;
        const { column, row } = params;
        if (!props) {
          return '';
        }
        // 使用 DictTag 组件替代原来的实现
        return h(DictTag, {
          type: props.type,
          value: row[column.field]?.toString(),
        });
      },
    });

    vxeUI.renderer.add('CellSwitch', {
      renderTableDefault({ attrs, props = {} }, { column, row }) {
        const loadingKey = `__loading_${column.field}`;

        // 使用解构赋值给 props 默认值
        const {
          checkedValue = 1,
          unCheckedValue = 0,
          checkedChildren = $t('common.enabled'),
          unCheckedChildren = $t('common.disabled'),
          ...otherProps
        } = props;

        // Element Plus Switch 组件属性映射
        const finallyProps = {
          modelValue: row[column.field],
          activeValue: checkedValue,
          inactiveValue: unCheckedValue,
          activeText: checkedChildren,
          inactiveText: unCheckedChildren,
          loading: row[loadingKey] ?? false,
          ...otherProps,
        };

        async function onChange(newVal: any) {
          row[loadingKey] = true;
          try {
            const result = await attrs?.beforeChange?.(newVal, row);
            if (result !== false) {
              row[column.field] = newVal;
            }
          } finally {
            row[loadingKey] = false;
          }
        }

        return h(ElSwitch, {
          ...finallyProps,
          'onUpdate:modelValue': onChange,
        });
      },
    });
    // 标签单元格
    vxeUI.renderer.add('CellTag', {
      renderTableDefault({ options, props }, { column, row }) {
        const value = get(row, column.field);
        const tagOptions = options ?? [
          { type: 'success', label: $t('common.enabled'), value: 1 },
          { type: 'danger', label: $t('common.disabled'), value: 0 },
        ];
        const tagItem = tagOptions.find((item) => item.value === value);
        return h(
          ElTag,
          {
            ...props,
            ...objectOmit(tagItem ?? {}, ['label']),
            type: tagItem?.type || 'info',
          },
          { default: () => tagItem?.label ?? value },
        );
      },
    });
    // 这里可以自行扩展 vxe-table 的全局配置，比如自定义格式化
    // vxeUI.formats.add
    // 操作列
    vxeUI.renderer.add('CellOperationBak', {
      renderTableDefault({ attrs, options, props }, { column, row }) {
        const defaultProps = {
          size: 'small',
          type: 'text',
          link: true,
          text: true,
          ...props,
        };
        const alignMap = {
          center: 'center',
          left: 'flex-start',
          right: 'flex-end',
          _fallback: 'flex-end',
        };
        const operations: Array<Recordable<any>> = (
          options || [
            {
              code: 'edit',
              type: 'primary',
            },
            {
              code: 'delete',
              type: 'danger',
            },
          ]
        )
          .map((opt) => {
            return { ...defaultProps, ...opt };
          })
          .map((opt) => {
            const optBtn: Recordable<any> = {};
            Object.keys(opt).forEach((key) => {
              optBtn[key] = isFunction(opt[key]) ? opt[key](row) : opt[key];
            });
            return optBtn;
          })
          .filter((opt) => opt.show !== false);

        // 合并配置的逻辑
        const mergeConfig = (opt: Recordable<any>) => {
          // 配置合并优先级：userOpt > 组件props > 全局默认
          return {
            ...globalButtonConfig.defaults,
            ...props,
            ...opt,
            // 特殊字段处理
            icon: undefined, // 始终禁用原生图标系统
            // 动态计算图标和文本
            _computedIcon: (opt.icon && opt.icon) || getIcon(opt.code),
            _computedTitle: (opt.title && opt.title) || getTitle(opt.code),
          };
        };

        function renderBtn(opt: Recordable<any>, listen = true) {
          const merged = mergeConfig(opt);

          return h(
            ElButton,
            {
              ...merged,
              // 清空按钮自带的 icon 属性（避免与插槽内容冲突）
              icon: undefined,
              onClick: listen
                ? () => attrs?.onClick?.({ code: merged.code, row })
                : undefined,
            },
            {
              default: () => [
                // 图标渲染
                h(IconifyIcon, {
                  icon: merged._computedIcon,
                  class: 'mr-1',
                  width: 14,
                  height: 14,
                }),
                // 文本渲染
                h('span', merged._computedTitle),
              ],
            },
          );
        }
        const btns = operations.map((opt) =>
          opt.code === 'delete' ? renderBtn(opt) : renderBtn(opt),
        );

        return h(
          'div',
          {
            class: 'flex items-center gap-1',
            style: {
              justifyContent: column.align
                ? alignMap[column.align]
                : 'flex-end',
              width: '100%',
            },
          },
          btns,
        );
      },
    });
    // 支持更多

    // 在 CellOperation 渲染器中修改
    vxeUI.renderer.add('CellOperation', {
      renderTableDefault({ attrs, options, props }, { column, row }) {
        const defaultProps = {
          size: 'small',
          type: 'text',
          link: true,
          text: true,
          ...props,
        };

        const alignMap = {
          center: 'center',
          left: 'flex-start',
          right: 'flex-end',
          _fallback: 'flex-end',
        };

        // 处理操作按钮配置
        const operations: Array<Recordable<any>> = (
          options || [
            {
              code: 'edit',
              type: 'primary',
            },
            {
              code: 'delete',
              type: 'danger',
            },
          ]
        )
          .map((opt) => ({ ...defaultProps, ...opt }))
          .map((opt) => {
            const optBtn: Recordable<any> = {};
            Object.keys(opt).forEach((key) => {
              optBtn[key] = isFunction(opt[key]) ? opt[key](row) : opt[key];
            });
            return optBtn;
          })
          .filter((opt) => opt.show !== false);

        // 合并配置的逻辑
        const mergeConfig = (opt: Recordable<any>) => {
          return {
            ...globalButtonConfig.defaults,
            ...props,
            ...opt,
            icon: undefined,
            _computedIcon: (opt.icon && opt.icon) || getIcon(opt.code),
            _computedTitle: (opt.title && opt.title) || getTitle(opt.code),
          };
        };

        // 渲染单个按钮
        function renderBtn(opt: Recordable<any>, listen = true) {
          const merged = mergeConfig(opt);
          return h(
            ElButton,
            {
              ...merged,
              icon: undefined,
              onClick: listen
                ? () => attrs?.onClick?.({ code: merged.code, row })
                : undefined,
            },
            {
              default: () => [
                h(IconifyIcon, {
                  icon: merged._computedIcon,
                  class: 'mr-1',
                  width: 14,
                  height: 14,
                }),
                h('span', merged._computedTitle),
              ],
            },
          );
        }

        // 判断是否需要显示更多下拉菜单
        const MAX_VISIBLE_BUTTONS = 3;
        const showMoreDropdown = operations.length >= MAX_VISIBLE_BUTTONS;

        // 可见按钮和隐藏按钮的分割
        const visibleButtons = showMoreDropdown
          ? operations.slice(0, MAX_VISIBLE_BUTTONS - 1) // 显示2个按钮 + 1个更多按钮
          : operations;

        const hiddenButtons = showMoreDropdown
          ? operations.slice(MAX_VISIBLE_BUTTONS - 1)
          : [];

        // 渲染可见按钮
        const visibleBtnElements = visibleButtons.map((opt) => renderBtn(opt));

        // 渲染更多下拉菜单
        let moreDropdownElement = null;
        if (showMoreDropdown && hiddenButtons.length > 0) {
          const dropdownItems = hiddenButtons.map((opt) => {
            const merged = mergeConfig(opt);
            return h(
              ElDropdownItem,
              {
                onClick: () => attrs?.onClick?.({ code: merged.code, row }),
              },
              {
                default: () => renderBtn(merged),
              },
            );
          });

          moreDropdownElement = h(
            ElDropdown,
            {
              trigger: 'hover',
              placement: 'bottom',
            },
            {
              default: () =>
                h(
                  ElButton,
                  {
                    size: 'small',
                    link: true,
                    text: true,
                    style: {
                      // 直接添加样式
                      outline: 'none',
                      boxShadow: 'none',
                      marginLeft: '4px',
                    },
                    onFocus: (e: Event) => {
                      // 移除焦点样式
                      (e.target as HTMLElement).style.outline = 'none';
                      (e.target as HTMLElement).style.boxShadow = 'none';
                    },
                  },

                  {
                    default: () => [
                      h('span', $t('更多')),
                      h(IconifyIcon, {
                        icon: 'mingcute:more-2-fill',
                        class: 'mr-1',
                        width: 14,
                        height: 14,
                      }),
                    ],
                  },
                ),
              dropdown: () =>
                h(ElDropdownMenu, {}, { default: () => dropdownItems }),
            },
          );
        }

        // 组合所有按钮元素
        const allBtnElements = showMoreDropdown
          ? [...visibleBtnElements, moreDropdownElement]
          : visibleBtnElements;

        return h(
          'div',
          {
            class: 'flex items-center gap-1',
            style: {
              justifyContent: column.align
                ? alignMap[column.align]
                : 'flex-end',
              width: '100%',
            },
          },
          allBtnElements,
        );
      },
    });

    vxeUI.formats.add('formatPast2', {
      tableCellFormatMethod({ cellValue }) {
        return formatPast2(cellValue);
      },
    });
  },
  useVbenForm,
});

export { useVbenVxeGrid };

export * from '#/components/table-action';
export type * from '@vben/plugins/vxe-table';
export type OnActionClickParams<T = Recordable<any>> = {
  code: string;
  row: T;
};
export type OnActionClickFn<T = Recordable<any>> = (
  params: OnActionClickParams<T>,
) => void;
